package main;

import java.math.BigDecimal;

import temperature.Temperature;
import be.kuleuven.cs.som.annotate.Immutable;
import dungeon.CompositeDungeon;
import dungeon.Level;
import dungeon.Shaft;
import dungeonElements.Door;
import dungeonElements.NormalSquare;
import dungeonElements.Rock;
import dungeonElements.Square;
import dungeonElements.TeleportationSquare;
import dungeonElements.TransparentSquare;
import dungeonTools.Coordinate;
import dungeonTools.Direction;

/**
 * Main class for the program. It demonstrates how teleportation
 * and room-detection scales across different dungeons placed next
 * to each other inside a composite dungeon
 * 
 * @author Tom Jacobs & Ewoud De Moor
 * @version 3.0
 */
public class Main {

	
	/**
	 * Creates a Composite Dungeon with in it 2 shafts and 2 levels.
	 * One of the shafts is completely sealed off from the rest by walls.
	 * The normal square at (7,1) has as its teleportation destination the
	 * normal square located at (7,6). The north east level is connected
	 * to the south west level by another shaft, filled with transparent
	 * squares. In that south west level, a closed door stands between
	 * the normal squares (5,3) and (6,3). Once this is opened, every
	 * square in the composite dungeon will be automatically reachable
	 * from our starting destination at (7,1).
	 * 
	 * 
	 * 	   8                        +-----------+
	 * 	                            |           | 
	 * 	   7                        |   +---#---#
	 * 	                            |   |?N?# N #
	 * 	   6                        |   |   #   #
	 * 	                            |   | N # N #
	 * 	   5                    +---+---+---#---#
	 * 	                        |   | T   T   T |
	 * 	   4    +---------------+---+---+---+---+
	 * 	        |               | N / N |
	 * 	   3    |               |   #####---+
	 * 	        |               | N ##### N |
	 * 	   2    |               |   #####   |
	 * 	        |               | N   N #?N?|
	 * 	   1    |               +---+---#---+
	 * 	        |                       |   |
	 * 	   0    +-----------------------+---+
	 * 		0   1   2   3   4   5   6   7   8   9
	 * 
	 * LEGEND:
	 * 
	 * | + - 	Square/Dungeon borders
	 * / 		Door
	 * #		Wall
	 * ###		Rock
	 * N 		NormalSquare
	 * T 		TransparentSquare
	 * ? ?		Teleportation Active
	 * 
	 * @param args
	 */
	@Immutable
	public static void main(String[] args) {
		System.out.println("This method creates a dungeon with the following layout.\n" +
				"	   8                        +-----------+\n" +
				"	                            |           |\n" +
				" 	   7                        |   +---#---#\n" +
				" 	                            |   |?N?# N #\n" +
				" 	   6                        |   |   #   #\n" +
				"      		                    |   | N # N #\n" +
				" 	   5                    +---+---+---#---#\n" +
				" 	                        |   | T   T   T |\n" +
				" 	   4    +---------------+---+---+---+---+\n" +
				" 	        |               | N / N |\n" +
				" 	   3    |               |   #####---+\n" +
				" 	        |               | N ##### N |\n" +
				" 	   2    |               |   #####   |\n" +
				" 	        |               | N   N #?N?|\n" +
				" 	   1    |               +---+---#---+\n" +
				" 	        |                       |   |\n" +
				"	   0    +-----------------------+---+\n" +
				"	    0   1   2   3   4   5   6   7   8   9\n" +
				" \n" +
				" LEGEND:\n" +
				" \n" +
				" | + - 		Square/Dungeon borders\n" +
				" / 		Door\n" +
				" #		Wall\n" +
				" ###		Rock\n" +
				" N 		NormalSquare\n" +
				" T 		TransparentSquare\n" +
				" ? ?		Teleportation Active\n" +
				"\n");
		dungeon = new CompositeDungeon<Square>(50,50,50);
		level = new Level<Square>(6,4);
		teleportationLevel = new Level<TeleportationSquare>(3, 3);
		shaft1 = new Shaft<TeleportationSquare>(Direction.NORTH, 3);
		shaft2 = new Shaft<TransparentSquare>(Direction.EAST, 4);
		dungeon.addDungeon(level, new Coordinate(1, 0, 0));
		//Creates and sets all squares in the south west level
		NormalSquare normalSquare_at_5_1 = new NormalSquare(Temperature.CELSIUS_0,10,false,false,false,false,false,true);
		NormalSquare normalSquare_at_6_1 = new NormalSquare(Temperature.CELSIUS_0,10,false,true,false,false,false,true);
		NormalSquare normalSquare_at_5_2 = new NormalSquare(Temperature.CELSIUS_0,10,false,false,false,false,false,true);
		NormalSquare normalSquare_at_5_3 = new NormalSquare(Temperature.CELSIUS_0,10,false,false,false,false,false,true);
		NormalSquare normalSquare_at_6_3 = new NormalSquare(Temperature.CELSIUS_0,10,false,false,false,false,false,true);
		Rock rock_at_6_2 = new Rock();
		normalSquare_at_5_3.buildDoor(Direction.EAST);
		((Door) normalSquare_at_5_3.getBorder(Direction.EAST)).closeDoor();
		dungeon.addSquare(normalSquare_at_6_3, new Coordinate(6, 3, 0));
		dungeon.addSquare(normalSquare_at_5_3, new Coordinate(5, 3, 0));
		dungeon.addSquare(normalSquare_at_5_2, new Coordinate(5, 2, 0));
		dungeon.addSquare(normalSquare_at_6_1, new Coordinate(6, 1, 0));
		dungeon.addSquare(normalSquare_at_5_1, new Coordinate(5, 1, 0));
		dungeon.addSquare(rock_at_6_2, new Coordinate(6, 2, 0));
		//Creates and sets all squares in the south east shaft
		dungeon.addDungeon(shaft1, new Coordinate(7,0,0));
		NormalSquare normalSquare_at_7_1 = new NormalSquare(Temperature.CELSIUS_0,10,false,false,false,false,false,true);
		NormalSquare normalSquare_at_7_2 = new NormalSquare(Temperature.CELSIUS_0,10,false,false,false,false,false,true);
		dungeon.addSquare(normalSquare_at_7_1, new Coordinate(7, 1, 0));
		dungeon.addSquare(normalSquare_at_7_2, new Coordinate(7, 2, 0));
		//Creates and sets all squares in the central shaft
		dungeon.addDungeon(shaft2, new Coordinate(5,4,0));
		TransparentSquare transparentSquare_at_6_4 = new TransparentSquare(new Temperature(BigDecimal.valueOf(300)), 60, Direction.CEILING, false);
		TransparentSquare transparentSquare_at_7_4 = new TransparentSquare(new Temperature(BigDecimal.valueOf(400)), 100, Direction.CEILING, false);;
		TransparentSquare transparentSquare_at_8_4 = new TransparentSquare(new Temperature(BigDecimal.valueOf(300)), 60, Direction.CEILING, false);
		dungeon.addSquare(transparentSquare_at_6_4, new Coordinate(6, 4, 0));
		dungeon.addSquare(transparentSquare_at_7_4, new Coordinate(7, 4, 0));
		dungeon.addSquare(transparentSquare_at_8_4, new Coordinate(8, 4, 0));
		//Creates and sets all squares in the north east level
		dungeon.addDungeon(teleportationLevel, new Coordinate(6,5,0));
		NormalSquare normalSquare_at_7_5 = new NormalSquare(Temperature.CELSIUS_0,10,false,false,false,false,false,true);
		NormalSquare normalSquare_at_7_6 = new NormalSquare(Temperature.CELSIUS_0,10,false,false,false,false,false,true);
		NormalSquare normalSquare_at_8_5 = new NormalSquare(Temperature.CELSIUS_0,10,false,true,false,true,false,true);
		NormalSquare normalSquare_at_8_6 = new NormalSquare(Temperature.CELSIUS_0,10,false,true,false,true,false,true);
		dungeon.addSquare(normalSquare_at_7_5, new Coordinate(7, 5, 0));
		dungeon.addSquare(normalSquare_at_7_6, new Coordinate(7, 6, 0));
		dungeon.addSquare(normalSquare_at_8_5, new Coordinate(8, 5, 0));
		dungeon.addSquare(normalSquare_at_8_6, new Coordinate(8, 6, 0));
		//Sets the teleportation:
		normalSquare_at_7_1.setTeleportationDestination(normalSquare_at_7_6);
		System.out.println("Coordinate (6,1) is reachable from (7,1): " + dungeon.isSquareReachable(normalSquare_at_7_1, normalSquare_at_6_1));
		System.out.println("\nState of the square at (6,1):\n" + normalSquare_at_6_1);
		((Door) normalSquare_at_5_3.getBorder(Direction.EAST)).openDoor();
		System.out.println("\nDoor between (5,3) and (6,3) opened.\n");
		System.out.println("Coordinate (6,1) is reachable from (7,1): " + dungeon.isSquareReachable(normalSquare_at_7_1, normalSquare_at_6_1));
		System.out.println("\nState of the square at (6,1):\n" + normalSquare_at_6_1);

	}
	
	/**
	 * Variable registering the Composite Dungeon used in the main method
	 */
	private static CompositeDungeon<Square> dungeon;
	
	/**
	 * Variable registering the South West Level used in the main method
	 */
	private static Level<Square> level;
	
	/**
	 * Variable registering the North West Level used in the main method
	 */
	private static Level<TeleportationSquare> teleportationLevel;
	
	/**
	 * Variable registering the South Shaft used in the main method
	 */
	private static Shaft<TeleportationSquare> shaft1;
	
	/**
	 * Variable registering the North Shaft used in the main method
	 */
	private static Shaft<TransparentSquare> shaft2;
}
